//    Copyright (C) Kherty.  All rights reserved.
using System.Collections.Generic;
using System.Collections.ObjectModel;
using OpenLS.Core.Serialization;

namespace OpenLS.Chart
{
    public class BubbleChart : ChartBase
    {
        private ObservableCollection<BubbleSeries> _series;
        private bool? bubble3D;
        private int bubbleScale;
        private DataLabels dlbls;
        private Axis firstAxis;

        private Axis secondAxis;
        private bool showNegBubbles;
        private SizeRepresents sizeRepresents;


        private bool varyColors;

        internal Axis FirstAxis
        {
            get { return firstAxis; }
            set { firstAxis = value; }
        }

        internal Axis SecondAxis
        {
            get { return secondAxis; }
            set { secondAxis = value; }
        }

        public bool VaryColors
        {
            get { return varyColors; }
            set { varyColors = value; notifyPropertyChanged("VaryColors");}
        }

        public ObservableCollection<BubbleSeries> Series
        {
            get
            {
                if (_series == null)
                    _series = CreateSeriesCollection<BubbleSeries>();
                return _series;
            }
        }

        public bool? Bubble3D
        {
            get { return bubble3D; }
            set { bubble3D = value; notifyPropertyChanged("Bubble3D");}
        }

        public int BubbleScale //\\ TODO: check range
        {
            get { return bubbleScale; }
            set { bubbleScale = value; notifyPropertyChanged("BubbleScale");}
        }


        public SizeRepresents SizeRepresents
        {
            get { return sizeRepresents; }
            set { sizeRepresents = value;notifyPropertyChanged("SizeRepresents"); }
        }

        public bool NegativeBubblesVisible
        {
            get { return showNegBubbles; }
            set { showNegBubbles = value; notifyPropertyChanged("NegativeBubblesVisible");}
        }

        public DataLabels DataLabels
        {
            get { return dlbls; }
            set { dlbls = value; notifyPropertyChanged("DataLabels");}
        }

        protected override void VerifyAxes()
        {
            this.firstAxis.CrossAxis = secondAxis;
            this.secondAxis.CrossAxis = firstAxis;
        }

        internal override void ReadXmlCore(ReadContext context)
        {
            using (var c = context.Read("bubbleChart"))
            {
                varyColors = ChartHelper.ReadVaryColors(c);
                Series.Clear();
                while (c.ReaderLocalName == "ser")
                {
                    var s = new BubbleSeries();
                    s.ReadXmlCore(c);
                    Series.Add(s);
                }
                DataLabels = c.ReadOptionalElement<DataLabels>(DataLabels.xmlName);
                Bubble3D = c.ReadOptionalElementBooleanAttribute("bubble3D");
                BubbleScale = c.ReadOptionalElementIntegerAttribute("bubbleScale", 100);
                NegativeBubblesVisible = c.ReadOptionalElementBooleanAttribute("showNegBubbles", false);
                SizeRepresents =
                    c.ReadOptionalElementEnumAttribute("sizeRepresents", SizeRepresents.Area);
                AxisResolver r = ReadContextData.GetAxisResolver(c);
                r.AddAction(c.ReadElementUIntegerAttribute("axId"), delegate(Axis a) { FirstAxis = a; });
                r.AddAction(c.ReadElementUIntegerAttribute("axId"), delegate(Axis a) { SecondAxis = a; });
                c.WarnIf("ext");
            }
        }

        internal override void WriteXmlCore(WriteContext context)
        {
            using (WriteContext c = context.Write("bubbleChart"))
            {
                ChartHelper.WriteVaryColors(context, VaryColors);
                foreach (BubbleSeries s in Series)
                {
                    c.WriteElement(s);
                }
                c.WriteOptionalElement(DataLabels);
                c.WriteOptionalElementBooleanAttribute("bubble3D", Bubble3D);
                c.WriteOptionalElementIntegerAttribute("bubbleScale", BubbleScale, 100);
                c.WriteOptionalElementBooleanAttribute("showNegBubbles", NegativeBubblesVisible);
                c.WriteOptionalElementEnumAttribute<SizeRepresents>("sizeRepresents", SizeRepresents);
                c.WriteElementUIntegerAttribute("axId", FirstAxis.Id);
                c.WriteElementUIntegerAttribute("axId", SecondAxis.Id);
                c.WarnIf("ext");
            }
        }

        internal override IEnumerable<Axis> GetAxes()
        {
            yield return FirstAxis;
            yield return SecondAxis;
        }
    }
}